<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>

    // 自定义构造函数  
    function Cat(name, color) {
        this.name = name;
        this.color = color;
    }

    Cat.prototype.species = "Cat";
    Cat.prototype.hall = function () {
        console.log("喵喵", "老吴");
    }
    Cat.prototype.skill = function () {
        console.log("捉老鼠", "卖萌");
    }
    Cat.prototype.say = function () {
        console.log(this.name, this.color);
    }

    // Cat.prototype.toString = function () {
    //     return "hello," + this.name;
    // }

    Object.prototype.a = 1;
    Object.prototype.b = 2;


    // 原型链:  实例化对象在查找属性和方法过程中的链式访问机制(顺着原型链访问)
    // Tom -> Tom.__proto__(Cat.prototype)  => Cat.prototype.__proto__(Object.prototype) => Object.prototype.__proto__(null)
    // Tom -> Cat.prototype -> Object.prototype -> null

    var Tom = new Cat("Tom", "black");
    // console.log(Tom);


    // toString()  将其他类型转化为字符串类型
    /* var num = 100;
    var str = "hello"
    var bool = true;
    var arr = [1, 2, 3];
    var obj = { a: 1, b: 2 };

    console.log(num.toString());  // 数字优先访问Number.prototype.toString  并没有访问 Object.prototype.toString
    console.log(str.toString());  // 字符串优先访问String.prototype.toString  并没有访问 Object.prototype.toString
    console.log(bool.toString()); // 布尔值优先访问Boolean.prototype.toString  并没有访问 Object.prototype.toString
    console.log(arr.toString());  // 数组优先访问Array.prototype.toString  并没有访问 Object.prototype.toString
    console.log(obj.toString());  //  访问 Object.prototype.toString  "[obejct Object]"
    console.log(Tom.toString());  // 访问 Object.prototype.toString   "[obejct Object]"

    console.log(arr);
    console.log(new Number(100)); */


    // valueOf()   返回实例化对象本身

    // var num = 100;
    // var str = "hello"
    // var bool = true;
    // var arr = [1, 2, 3];
    // var obj = { a: 1, b: 2 };

    // console.log(num.valueOf());
    // console.log(str.valueOf());
    // console.log(bool.valueOf());
    // console.log(arr.valueOf());
    // console.log(obj.valueOf());
    // console.log(Tom.valueOf());


    // isPrototypeOf    判断 某个构造函数的原型对象 是否存在于 某个实例化对象的原型链上
    // 自实例化对象Tom起的原型链:  Tom -> Cat.prototype -> Object.prototype -> null

    // console.log(Cat.prototype.isPrototypeOf(Tom));  // true
    // console.log(Object.prototype.isPrototypeOf(Tom)); // true
    // console.log(Array.prototype.isPrototypeOf(Tom)); // false

    // 拓展
    // instanceof   判断 某个实例化对象  的原型链上,是否存在 某个构造函数 的原型对象
    // console.log(Tom instanceof Cat);  // true
    // console.log(Tom instanceof Object); // true
    // console.log(Tom instanceof Array); //false


    // hasOwnProperty()   判断某个实例化对象上,是否存在某个属性 (只查找实例化对象本身,不查找原型链)
    // Object.hasOwn()   判断某个实例化对象上,是否存在某个属性 (只查找实例化对象本身,不查找原型链)
    console.log(Tom);

    // 所有实例化对象均可访问  Object.prototype的方法
    // console.log(Tom.hasOwnProperty("name"));  // true
    // console.log(Tom.hasOwnProperty("color"));  // true
    // console.log(Tom.hasOwnProperty("species")); // false
    // console.log(Tom.hasOwnProperty("a"));  // false
    // console.log(Tom.hasOwnProperty("b"));  // false


    // 构造函数Object的静态方法
    // console.log(Object.hasOwn(Tom, "name"));  // true
    // console.log(Object.hasOwn(Tom, "color"));  // true
    // console.log(Object.hasOwn(Tom, "species")); // false
    // console.log(Object.hasOwn(Tom, "a"));  // false
    // console.log(Object.hasOwn(Tom, "b"));  // false

    // 拓展
    // in 语法     判断 某个属性 是否存在于 某个实例化对象 的原型链上

    // for (var key in Tom) {
    //     console.log(key);
    // }


    // console.log("name" in Tom);  // true
    // console.log("color" in Tom); // true
    // console.log("species" in Tom); // true
    // console.log("a" in Tom);  // true
    // console.log("b" in Tom);  // true
    // console.log("hello" in Tom); // false


    // propertyIsEnumerable()  判断某个实例化对象上的某个属性,是否可以被枚举(遍历)  => 只查找实例化对象本身

    console.log(Tom.propertyIsEnumerable("name"));  // true
    console.log(Tom.propertyIsEnumerable("color"));  // true
    console.log(Tom.propertyIsEnumerable("species")); // false
    console.log(Tom.propertyIsEnumerable("a"));  // false
    console.log(Tom.propertyIsEnumerable("b"));  // false




</script>

</html>